import XLSX from 'xlsx'

// 导入
function importExcel(files) {
  return new Promise((resolve, reject) => {
    // 通过FileReader对象读取文件
    const fileReader = new FileReader()
    fileReader.onload = event => {
      try {
        const { result } = event.target
        // 以二进制流方式读取得到整份excel表格对象
        const workbook = XLSX.read(result, { type: 'binary' })
        // 存储获取到的数据
        let data = []
        // 遍历每张工作表进行读取（这里默认只读取第一张表）
        for (const sheet in workbook.Sheets) {
          // esline-disable-next-line
          if (Object.prototype.hasOwnProperty.call(workbook.Sheets, sheet)) {
            // 利用 sheet_to_json 方法将 excel 转成 json 数据
            data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet], { defval: '' }))
            // break; // 如果只取第一张表，就取消注释这行
          }
        }
        // 最终获取到并且格式化后的 json 数据
        // console.log(data);
        resolve({ name: files.name, data: data })
      } catch (e) {
        // 这里可以抛出文件类型错误不正确的相关提示
        console.error(e)
      }
    }
    // 以二进制方式打开文件
    fileReader.readAsBinaryString(files.raw)
  })
}

// 导出
function exportExcel(data, name, sheetNamesList, type, merge) {
  const sheetNames = sheetNamesList.map(i => i.slice(-31))
  const wb = XLSX.utils.book_new()
  data.forEach((element, index) => {
    let sheet
    if (type === 'array') {
      sheet = XLSX.utils.aoa_to_sheet(element)
      element[1] &&
        (sheet['!cols'] = element[1].map(i => {
          return { wch: i ? i.toString().length * 1.5 : 10 }
        }))
    } else {
      sheet = XLSX.utils.json_to_sheet(element)
    }
    if (merge) {
      sheet['!ref'] = `A1:AI${element.length}`
      sheet['!merges'] = merge
    }
    XLSX.utils.book_append_sheet(wb, sheet, sheetNames[index] || 'sheet' + (index + 1))
  })
  const workbookBlob = workbook2blob(wb)
  openDownloadDialog(workbookBlob, name + '.xlsx')
}

function workbook2blob(workbook) {
  // 生成excel的配置项
  const wopts = {
    // 要生成的文件类型
    bookType: 'xlsx',
    // // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
    bookSST: false,
    type: 'binary'
  }
  const wbout = XLSX.write(workbook, wopts)
  // 将字符串转ArrayBuffer
  function s2ab(s) {
    const buf = new ArrayBuffer(s.length)
    const view = new Uint8Array(buf)
    for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
  }
  const blob = new Blob([s2ab(wbout)], {
    type: 'application/octet-stream'
  })
  return blob
}

const tableToExcel = (id, name, other) => {
  const table = document.querySelector('#' + id)
  const fixedTable = document.querySelector('#' + id).querySelector('.el-table__fixed') || null
  if (fixedTable) {
    const popovers = fixedTable.querySelectorAll('.el-popover')
    popovers.forEach(i => {
      i.parentNode.removeChild(i)
    })
  }
  const workbook = XLSX.utils.book_new()
  const worksheet = XLSX.utils.aoa_to_sheet([])
  if (other) {
    XLSX.utils.sheet_add_aoa(worksheet, other, { origin: 'A1' })
    worksheet['!merges'] = [
      // 设置A1-C1的单元格合并
      { s: { r: 0, c: 0 }, e: { r: 0, c: 2 }},
      { s: { r: 0, c: 4 }, e: { r: 0, c: 6 }},
      { s: { r: 0, c: 8 }, e: { r: 0, c: 10 }}
    ]
  }
  XLSX.utils.sheet_add_dom(worksheet, fixedTable || table, {
    raw: true,
    origin: other ? 'A3' : 'A1'
  })
  XLSX.utils.book_append_sheet(workbook, worksheet, 'sheet1')
  const wbout = XLSX.write(workbook, {
    bookType: 'xlsx',
    bookSST: true,
    type: 'array'
  })
  // console.log('wbout', wbout)
  const bolb = new Blob([wbout], { type: 'application/octet-stream' })
  openDownloadDialog(bolb, name + '.xlsx')
}

function openDownloadDialog(blob, fileName) {
  if (typeof blob === 'object' && blob instanceof Blob) {
    blob = URL.createObjectURL(blob)
  }
  const aLink = document.createElement('a')
  aLink.href = blob
  // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，有时候 file:///模式下不会生效
  aLink.download = fileName || ''
  let event
  if (window.MouseEvent) event = new MouseEvent('click')
  //   移动端
  else {
    event = document.createEvent('MouseEvents')
    event.initMouseEvent(
      'click',
      true,
      false,
      window,
      0,
      0,
      0,
      0,
      0,
      false,
      false,
      false,
      false,
      0,
      null
    )
  }
  aLink.dispatchEvent(event)
}

export { exportExcel, importExcel, tableToExcel }
